home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / demos / OpenGL / backtrace / callbacks.c++ < prev    next >
C/C++ Source or Header  |  1996-11-11  |  9KB  |  319 lines

  1. /*
  2.  * (c) Copyright 1993, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED 
  4.  * Permission to use, copy, modify, and distribute this software for 
  5.  * any purpose and without fee is hereby granted, provided that the above
  6.  * copyright notice appear in all copies and that both the copyright notice
  7.  * and this permission notice appear in supporting documentation, and that 
  8.  * the name of Silicon Graphics, Inc. not be used in advertising
  9.  * or publicity pertaining to distribution of the software without specific,
  10.  * written prior permission. 
  11.  *
  12.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  13.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  14.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  15.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  16.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  17.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  18.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  19.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  20.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  21.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  22.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  23.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  24.  * 
  25.  * US Government Users Restricted Rights 
  26.  * Use, duplication, or disclosure by the Government is subject to
  27.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  28.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  29.  * clause at DFARS 252.227-7013 and/or in similar or successor
  30.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  31.  * Unpublished-- rights reserved under the copyright laws of the
  32.  * United States.  Contractor/manufacturer is Silicon Graphics,
  33.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  34.  *
  35.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  36.  */
  37. #include <X11/keysym.h>
  38.  
  39. #include <X11/Intrinsic.h>
  40. #include <Xm/Xm.h>
  41. #include <Xm/ToggleB.h>
  42.  
  43. #include <GL/glu.h>
  44. #include <GL/glx.h>
  45. #include <GL/GLwMDrawA.h>
  46.  
  47. #include <math.h>
  48. #include <stdio.h>
  49. #include <stdlib.h>
  50. #include <sys/time.h>
  51.  
  52. #include "scene.h"
  53. #include "callbacks.h"
  54.  
  55. extern Widget glw;
  56. extern XtAppContext app_context;
  57. GLXContext glx_context;
  58.  
  59. extern int quick_moves;
  60.  
  61. extern int auto_motion;
  62. static float dtheta[nlights];
  63. static float last_motion_update;
  64. struct timeval starttime;
  65.  
  66. static int button_down;
  67. static int winx, winy;
  68.  
  69. static int name_selected;
  70.  
  71. static XtWorkProcId workproc = NULL;
  72.  
  73. const float time_fudge = .0001;
  74.  
  75. inline float current_time()
  76. {
  77.   struct timeval time;
  78.   gettimeofday(&time, NULL);
  79.   return ((double)(time.tv_sec - starttime.tv_sec) + 
  80.       (double)(time.tv_usec - starttime.tv_usec) / 1000000.0);
  81. }
  82.  
  83. inline float rand(float min, float max) 
  84. {
  85.   double r;
  86.   r = (double)rand() / (double)RAND_MAX;
  87.   return min + r * (max - min);
  88. }
  89.  
  90. static void draw()
  91. {
  92.   GLwDrawingAreaMakeCurrent(glw, glx_context);
  93.   scene_draw();
  94.   GLwDrawingAreaSwapBuffers(glw);
  95. }
  96.  
  97. void intToggleCB(Widget w, XtPointer client_data, XtPointer call_data)
  98. {
  99.   int *data;
  100.   XmToggleButtonCallbackStruct *ptr;
  101.   ptr = (XmToggleButtonCallbackStruct *)call_data;
  102.   data = (int *)client_data;
  103.   *data = ptr->set;
  104.   // This redraw may or may not be needed - do it to be safe
  105.   draw();
  106. }
  107.  
  108. void resetLightsCB(Widget w)
  109. {
  110.   scene_reset_lights();
  111.   draw();
  112. }
  113.  
  114. void autoMotionCB(Widget w, XtPointer client_data, XtPointer call_data)
  115. {
  116.   int i;
  117.   XmToggleButtonCallbackStruct *ptr;
  118.  
  119.   ptr = (XmToggleButtonCallbackStruct *)call_data;
  120.  
  121.   auto_motion = ptr->set;
  122.   if (auto_motion) {
  123.     workproc = XtAppAddWorkProc(app_context, drawWP, NULL);
  124.     for (i = 0; i < nlights; i++) dtheta[i] = rand(-1, 1);
  125.     last_motion_update = current_time();
  126.   } else {
  127.     XtRemoveWorkProc(workproc);
  128.   }
  129. }
  130.  
  131.  
  132. void initCB(Widget w)
  133. {
  134.   Arg args[1];
  135.   XVisualInfo *vi;
  136.  
  137.   XtSetArg(args[0], GLwNvisualInfo, &vi);
  138.   XtGetValues(w, args, 1);
  139.  
  140.   glx_context = glXCreateContext(XtDisplay(w), vi, 0, GL_FALSE);
  141.   GLwDrawingAreaMakeCurrent(w, glx_context);
  142.  
  143.   scene_init(); 
  144.  
  145.   gettimeofday(&starttime, NULL);
  146.   srand(starttime.tv_usec);
  147. }
  148.  
  149. void exposeCB(Widget w)
  150. {
  151.   draw();
  152. }
  153.  
  154. void resizeCB(Widget w, XtPointer client_data, XtPointer call)
  155. {
  156.   GLwDrawingAreaCallbackStruct *call_data;
  157.   call_data = (GLwDrawingAreaCallbackStruct *)call;
  158.  
  159.   GLwDrawingAreaMakeCurrent(w, glx_context);
  160.   winx = call_data->width;
  161.   winy = call_data->height;
  162.  
  163.   glViewport(0, 0, winx, winy);
  164.  
  165.   aspect = (GLfloat)winx / (GLfloat)winy;
  166. }
  167.  
  168. void inputCB(Widget w, XtPointer client_data, XtPointer call_data)
  169. {
  170.   int picked;
  171.   GLwDrawingAreaCallbackStruct *call;
  172.  
  173.   char buffer[5];
  174.   int bufsize = 5;
  175.   KeySym key;
  176.   XComposeStatus compose;
  177.  
  178.   static int mousex, mousey;
  179.   /* Just to confuse everybody, I've made these go from 0-1. */
  180.   float dmousex, dmousey;
  181.   float r1, r2;
  182.  
  183.   call = (GLwDrawingAreaCallbackStruct *)call_data;
  184.   
  185.   GLwDrawingAreaMakeCurrent(w, glx_context);
  186.   switch(call->event->type) {
  187.   case ButtonPress:
  188.     button_down = call->event->xbutton.button;
  189.     mousex = call->event->xbutton.x;
  190.     mousey = call->event->xbutton.y;
  191.     picked = scene_pick(mousex, mousey);
  192.     if (picked >= name_lights) name_selected = picked;
  193.     break;
  194.   case ButtonRelease:
  195.     if (quick_moves) 
  196.       scene_move_update(name_selected, button_down == Button2, 
  197.             button_down == Button3, button_down = Button1);
  198.     button_down = 0; 
  199.     break;
  200.   case MotionNotify:
  201.     if (button_down == Button1) {
  202.       /* This is the "default" mouse button - moves things in theta
  203.        * since this is easy and computationally cheap */
  204.       dmousex = (double)(call->event->xmotion.x - mousex) / (double)winx;
  205.       scene_move(name_selected, 0, 0, dmousex, quick_moves ? 0 : 1);
  206.     } else if (button_down == Button2) {
  207.       /* Change the radius - figue out the component of the mouse motion
  208.        * that's going toward the center of the screen */
  209.       mousex = (winx / 2) - mousex;
  210.       mousey = (winy / 2) - mousey;
  211.       r1 = sqrt((float)(mousex*mousex) / (float)(winx*winx) + 
  212.         (float)(mousey*mousey) / (float)(winy*winy));
  213.       mousex = call->event->xmotion.x;
  214.       mousey = call->event->xmotion.y;
  215.       mousex = (winx / 2) - mousex;
  216.       mousey = (winy / 2) - mousey;
  217.       r2 = sqrt((float)(mousex*mousex) / (float)(winx*winx) + 
  218.         (float)(mousey*mousey) / (float)(winy*winy));
  219.       scene_move(name_selected, r2 - r1, 0, 0, quick_moves ? 0 : 1);
  220.     } else if (button_down == Button3) {
  221.       /* Change phi - this is expensive */
  222.       dmousex = (double)(call->event->xmotion.x - mousex) / (double)winx;
  223.       scene_move(name_selected, 0, dmousex, 0, quick_moves ? 0 : 1);
  224.     }
  225.     mousex = call->event->xmotion.x;
  226.     mousey = call->event->xmotion.y;
  227.     break;
  228.   case KeyPress:
  229.     XLookupString(&(call->event->xkey), buffer, bufsize, &key, &compose);
  230.     if (key == XK_Escape) exit(0);
  231.     break;                            
  232.   default:
  233.     break;
  234.   }
  235.  
  236.   draw();
  237. }
  238.  
  239. void drawAllCB(Widget w)
  240. {
  241.   draw_square = 1;
  242.   draw_shadows = 1;
  243.   draw_refraction = 1;
  244.   draw_sphere = 1;
  245.   draw_lights = 1;
  246.   draw();
  247. }
  248.  
  249. void drawSomethingCB(Widget w, XtPointer client_data, XtPointer call_data)
  250. {
  251.   XmToggleButtonCallbackStruct *ptr;
  252.   int *data;
  253.   int i;
  254.  
  255.   ptr = (XmToggleButtonCallbackStruct *)call_data;
  256.   data = (int *)client_data;
  257.   *data = ptr->set;
  258.   draw();
  259. }
  260.  
  261. void refractionCB(Widget w, XtPointer client_data, XtPointer call_data)
  262. {
  263.   XmToggleButtonCallbackStruct *ptr;
  264.   GLfloat refraction;
  265.  
  266.   ptr = (XmToggleButtonCallbackStruct *)call_data;
  267.   if (!ptr->set) return;
  268.   refraction = *((GLfloat *)client_data);
  269.   refraction_change(refraction);
  270.   draw();
  271. }
  272.  
  273. void subdivisionCB(Widget w, XtPointer client_data, XtPointer call_data)
  274. {
  275.   XmToggleButtonCallbackStruct *ptr;
  276.   int subdivisions;
  277.  
  278.   ptr = (XmToggleButtonCallbackStruct *)call_data;
  279.   if (!ptr->set) return;
  280.   subdivisions = *((int *)client_data);
  281.   divisions_change(subdivisions);
  282.   draw();
  283. }
  284.  
  285. void light_onCB(Widget w, XtPointer client_data, XtPointer call_data)
  286. {
  287.   XmToggleButtonCallbackStruct *ptr;
  288.  
  289.   ptr = (XmToggleButtonCallbackStruct *)call_data;
  290.   lights_onoff((light *)client_data - lights, ptr->set);
  291.   draw();
  292. }
  293.  
  294. void exitCB(Widget w, XtPointer client_data, XtPointer call_data)
  295. {
  296.   exit(0);
  297. }
  298.  
  299. Boolean drawWP(XtPointer data)
  300. {
  301.   float t, dt;
  302.   int i;
  303.  
  304.   t = current_time();
  305.   dt = t - last_motion_update;
  306.   if (dt < time_fudge) return FALSE;
  307.  
  308.   for (i = 0; i < nlights; i++) {
  309.     scene_move(name_lights + i, 0, 0, dtheta[i] * dt, 1);
  310.   }
  311.  
  312.   last_motion_update = t;
  313.  
  314.   draw();
  315.   return FALSE;
  316. }
  317.  
  318.  
  319.